package cn.inyaa.admin.blog.service;

import cn.inyaa.admin.blog.bean.InyaaBlog;
import cn.inyaa.admin.blog.bean.InyaaBlogArticle;
import cn.inyaa.admin.blog.bean.InyaaBlogTag;
import cn.inyaa.admin.blog.bean.InyaaTag;
import cn.inyaa.admin.blog.dao.InyaaBlogArticleDao;
import cn.inyaa.admin.blog.dao.InyaaBlogDao;
import cn.inyaa.admin.blog.dao.InyaaBlogTagDao;
import cn.inyaa.admin.blog.dao.InyaaTagDao;
import cn.inyaa.admin.blog.dto.InyaaBlogDto;
import cn.inyaa.admin.blog.vo.InyaaBlogArchiveVo;
import cn.inyaa.admin.blog.vo.InyaaBlogVo;
import cn.inyaa.admin.config.RedisService;
import cn.inyaa.admin.sys.dto.LoginUser;
import com.inyaa.base.bean.BaseResult;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.security.Principal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
@RequiredArgsConstructor
@Transactional
public class InyaaBlogService {

    private final InyaaBlogDao inyaaBlogDao;
    private final InyaaBlogArticleDao inyaaBlogArticleDao;
    private final RedisService redisService;
    private final InyaaBlogTagDao inyaaBlogTagDao;
    private final InyaaTagDao inyaaTagDao;

    public List<InyaaBlog> findAll(InyaaBlog req) {
        ExampleMatcher matcher = ExampleMatcher.matching();
        Example<InyaaBlog> ex = Example.of(req, matcher);
        return inyaaBlogDao.findAll(ex);
    }

    public Page<InyaaBlogVo> findBlogListPage(InyaaBlogDto req) {
        Page<InyaaBlogVo> page = inyaaBlogDao.findBlogListPage(req);
        page.getContent().forEach(dto -> {
            List<Integer> tagId = inyaaBlogTagDao.findTagList(dto.getId());
            List<InyaaTag> tagList = inyaaTagDao.findByIdIn(tagId);
            dto.setTagList(tagList);
        });
        return page;
    }

    @Transactional
    public void save(InyaaBlogDto req, Principal principal) {
        InyaaBlog blog = new InyaaBlog();
        BeanUtils.copyProperties(req, blog);
        if (req.getId() != null) {
            blog.setUpdateTime(LocalDateTime.now());
        } else {
            blog.setCreateTime(LocalDateTime.now());
            blog.setViews(0);
            blog.setComments(0);
        }
        LoginUser loginUser = (LoginUser) redisService.get(principal.getName());
        blog.setUserId(loginUser.getId());
        inyaaBlogDao.save(blog);
        inyaaBlogArticleDao.deleteByBlogId(blog.getId());
        InyaaBlogArticle article = new InyaaBlogArticle();
        article.setBlogId(blog.getId());
        article.setContext(req.getContext());
        inyaaBlogArticleDao.save(article);

        inyaaBlogTagDao.deleteByBlogId(blog.getId());
        if (req.getTagList() != null && req.getTagList().size() > 0) {
            List<InyaaBlogTag> tagList = new ArrayList<>();
            req.getTagList().forEach(tag -> {
                InyaaBlogTag blogTag = new InyaaBlogTag();
                blogTag.setBlogId(blog.getId());
                blogTag.setTagId(tag);
                tagList.add(blogTag);
            });
            inyaaBlogTagDao.saveAll(tagList);
        }
    }

    public void delete(InyaaBlog req) {
        inyaaBlogTagDao.deleteByBlogId(req.getId());
        inyaaBlogDao.deleteById(req.getId());
        inyaaBlogArticleDao.deleteByBlogId(req.getId());
    }

    public InyaaBlogDto getBlogInfo(InyaaBlog req) {
        InyaaBlog blog = inyaaBlogDao.getOne(req.getId());
        InyaaBlogDto dto = new InyaaBlogDto();
        BeanUtils.copyProperties(blog, dto);
        InyaaBlogArticle article = inyaaBlogArticleDao.getByBlogId(dto.getId());
        if (article != null) {
            dto.setContext(article.getContext());
        }

        List<Integer> tagId = inyaaBlogTagDao.findTagList(dto.getId());
        dto.setTagList(tagId);
        return dto;
    }

    public BaseResult<List<InyaaBlogArchiveVo>> archive() {
        List<InyaaBlogArchiveVo> list = inyaaBlogDao.findArchiveList();
        list.forEach(obj -> {
            // 查询每一个时间点中的文章
            obj.setArchivePosts(inyaaBlogDao.findByArchiveDate(obj.getArchiveDate()));
        });
        return BaseResult.success(list);
    }
}
